#include "Analysis/LivenessAnalysis.h"
#include "Function.h"
#include "Instruction.h"
#include "Instructions/LoadInstruction.h"
#include <iostream>
#include <typeinfo>

// 对函数进行活跃变量分析
void LivenessAnalysis::analyze(Function * func)
{
    auto & insts = func->getInterCode().getInsts();
    std::map<Instruction *, std::set<std::string>> useSets, defSets;

    // 1. 预处理每条指令的use/def集合
    for (auto * inst: insts) {
        std::set<std::string> use, def;
        for (const auto & v: inst->getUseVars())
            use.insert(v);
        for (const auto & v: inst->getDefVars())
            def.insert(v);
        useSets[inst] = use;
        defSets[inst] = def;
    }

    // 2. 初始化in/out集合为空
    inSets.clear();
    outSets.clear();
    for (auto * inst: insts) {
        inSets[inst] = {};
        outSets[inst] = {};
    }

    // 3. 迭代求解in/out集合（逆序线性扫描）
    bool changed;
    do {
        changed = false;
        for (int i = (int) insts.size() - 1; i >= 0; --i) {
            Instruction * inst = insts[i];
            std::set<std::string> old_in = inSets[inst];
            std::set<std::string> old_out = outSets[inst];

            // out[n] = in[n+1]（线性IR，下一条指令的in集合）
            std::set<std::string> out;
            if (i + 1 < (int) insts.size()) {
                out = inSets[insts[i + 1]];
            }
            outSets[inst] = out;

            // in[n] = use[n] ∪ (out[n] - def[n])
            std::set<std::string> in = useSets[inst];
            for (const auto & v: out) {
                if (defSets[inst].count(v) == 0) {
                    in.insert(v);
                }
            }
            inSets[inst] = in;

            if (in != old_in || out != old_out) {
                changed = true;
            }
        }
    } while (changed);
}

// 获取某条指令的活跃变量集合
const std::set<std::string> & LivenessAnalysis::getInSet(Instruction * inst) const
{
    static std::set<std::string> empty;
    auto it = inSets.find(inst);
    return it != inSets.end() ? it->second : empty;
}

// 获取所有变量的活跃区间（变量名 -> [start, end] 指令下标）
std::map<std::string, std::pair<int, int>> LivenessAnalysis::getLiveIntervals(Function * func) const
{
    std::map<std::string, int> defPos, firstUsePos, lastUsePos;
    auto & insts = func->getInterCode().getInsts();

    // 打印LOAD指令的枚举值，用于确认
    std::cout << "IRINST_OP_LOAD enum value: " << static_cast<int>(IRInstOperator::IRINST_OP_LOAD) << std::endl;

    for (int i = 0; i < (int) insts.size(); ++i) {
        Instruction * inst = insts[i];

        // 1. 处理普通的 def/use（SSA临时变量）
        for (const auto & var: inst->getDefVars()) {
            if (defPos.count(var) == 0)
                defPos[var] = i;
        }
        for (const auto & var: inst->getUseVars()) {
            if (firstUsePos.count(var) == 0)
                firstUsePos[var] = i;
            lastUsePos[var] = i;
        }

        // 2. 通过指令的文本表示识别加载操作
        std::string instText;
        inst->toString(instText);
        if (instText.find(" = load ") != std::string::npos) {
            std::cout << "Found LOAD operation in text: " << instText << std::endl;

            // 修正解析逻辑：解析 "%result = load type, type* %ptr" 格式
            size_t equalPos = instText.find('=');

            if (equalPos != std::string::npos) {
                // 提取结果变量（等号左边）
                std::string resultName = instText.substr(0, equalPos);
                // 去除前后空格
                size_t start = resultName.find_first_not_of(" \t");
                size_t end = resultName.find_last_not_of(" \t");
                if (start != std::string::npos && end != std::string::npos) {
                    resultName = resultName.substr(start, end - start + 1);
                }

                // 寻找逗号后的指针变量
                size_t commaPos = instText.find(',');
                std::string ptrName;
                if (commaPos != std::string::npos) {
                    // 在逗号后寻找 %ptr
                    std::string afterComma = instText.substr(commaPos + 1);
                    size_t ptrPos = afterComma.find('%');
                    if (ptrPos != std::string::npos) {
                        // 提取从 % 开始到下一个空格、制表符或换行符的内容
                        size_t endPos = afterComma.find_first_of(" \t\n", ptrPos);
                        if (endPos == std::string::npos) {
                            endPos = afterComma.length();
                        }
                        ptrName = afterComma.substr(ptrPos, endPos - ptrPos);
                    }
                }

                std::cout << "Load result: " << resultName << ", ptr: " << ptrName << std::endl;

                // 处理结果变量（被定义）
                if (!resultName.empty() && resultName[0] != '.' && resultName.find(".L") != 0) {
                    if (defPos.count(resultName) == 0)
                        defPos[resultName] = i;
                }

                // 处理指针变量（被使用）
                if (!ptrName.empty() && ptrName[0] != '.' && ptrName.find(".L") != 0) {
                    if (firstUsePos.count(ptrName) == 0)
                        firstUsePos[ptrName] = i;
                    lastUsePos[ptrName] = i + 1;
                }
            }
        }

        // 3. 特殊处理 store 指令：store <value>, <type>* <ptr>
        if (instText.find("store ") != std::string::npos) {
            std::cout << "Found STORE operation in text: " << instText << std::endl;

            // 解析 store 指令格式：store <type> <value>, <type>* <ptr>
            size_t storePos = instText.find("store ");
            if (storePos != std::string::npos) {
                std::string afterStore = instText.substr(storePos + 6); // 跳过 "store "

                // 找到第一个逗号，分离 value 和 ptr 部分
                size_t commaPos = afterStore.find(',');
                if (commaPos != std::string::npos) {
                    // 提取被存储的值（逗号前）
                    std::string valuePart = afterStore.substr(0, commaPos);
                    std::string ptrPart = afterStore.substr(commaPos + 1);

                    // 从 value 部分提取变量名（最后一个 % 后的内容）
                    size_t valuePercentPos = valuePart.find_last_of('%');
                    std::string valueName;
                    if (valuePercentPos != std::string::npos) {
                        size_t valueEndPos = valuePart.find_first_of(" \t\n", valuePercentPos);
                        if (valueEndPos == std::string::npos) {
                            valueEndPos = valuePart.length();
                        }
                        valueName = valuePart.substr(valuePercentPos, valueEndPos - valuePercentPos);
                    }

                    // 从 ptr 部分提取指针变量名
                    size_t ptrPercentPos = ptrPart.find('%');
                    std::string ptrName;
                    if (ptrPercentPos != std::string::npos) {
                        size_t ptrEndPos = ptrPart.find_first_of(" \t\n", ptrPercentPos);
                        if (ptrEndPos == std::string::npos) {
                            ptrEndPos = ptrPart.length();
                        }
                        ptrName = ptrPart.substr(ptrPercentPos, ptrEndPos - ptrPercentPos);
                    }

                    std::cout << "Store value: " << valueName << ", ptr: " << ptrName << std::endl;

                    // 处理被存储的值（被使用）
                    if (!valueName.empty() && valueName[0] != '.' && valueName.find(".L") != 0) {
                        if (firstUsePos.count(valueName) == 0)
                            firstUsePos[valueName] = i;
                        lastUsePos[valueName] = i;
                    }

                    // 处理指针变量（被定义，因为内存内容改变）
                    if (!ptrName.empty() && ptrName[0] != '.' && ptrName.find(".L") != 0) {
                        if (defPos.count(ptrName) == 0)
                            defPos[ptrName] = i;
                    }
                }
            }
        }
    }

    // 3. 合并为活跃区间，过滤掉常量
    std::map<std::string, std::pair<int, int>> intervals;
    std::set<std::string> allVars;

    for (const auto & kv: defPos)
        allVars.insert(kv.first);
    for (const auto & kv: firstUsePos)
        allVars.insert(kv.first);
    for (const auto & kv: lastUsePos)
        allVars.insert(kv.first);

    for (const auto & var: allVars) {
        // 通过变量名找到对应的Value对象来检查是否为常量
        bool isConstant = false;

        // 从指令中查找该变量对应的Value对象
        for (auto * inst: insts) {
            // 检查操作数中是否有该变量
            for (const auto & operand: inst->getOperandsValue()) {
                if (operand && operand->getIRName() == var && operand->isConst()) {
                    isConstant = true;
                    break;
                }
            }
            if (isConstant)
                break;

            // 检查指令本身是否定义了该变量且为常量
            if (inst->getIRName() == var && inst->isConst()) {
                isConstant = true;
                break;
            }
        }

        // 跳过常量变量
        if (isConstant) {
            continue;
        }

        int start = -1, end = -1;

        // 确定起始点：第一次定义 或 第一次使用
        if (defPos.count(var)) {
            start = defPos[var];
        } else if (firstUsePos.count(var)) {
            start = firstUsePos[var];
        }

        // 确定结束点：最后一次使用
        if (lastUsePos.count(var)) {
            end = lastUsePos[var];
        } else if (defPos.count(var)) {
            end = defPos[var]; // 只定义未使用
        }

        if (start != -1 && end != -1) {
            intervals[var] = {start, end};
        }
    }

    return intervals;
}

// 输出每条指令的活跃变量集合
void LivenessAnalysis::printLiveness(Function * func) const
{
    auto & insts = func->getInterCode().getInsts();
    for (auto * inst: insts) {
        std::string ir;
        inst->toString(ir);
        std::cout << "[LIVE IN] { ";
        for (const auto & v: getInSet(inst)) {
            std::cout << v << " ";
        }
        std::cout << "}  |  " << ir << std::endl;
    }
}
